package org.fujene.memoryblock.local;

import java.io.IOException;

import org.fujene.memoryblock.MemoryBlock;
import org.fujene.structure.Constants;
import org.fujene.structure.LookupPointer;
import org.fujene.toolbox.ByteConverter;

/**
 * そのうちドキュメント書きます
 */
public class LocalInvertIndexBlock extends MemoryBlock{
	private int opt_length = 0;

	public LocalInvertIndexBlock(int bodySize, int ID, boolean isAllocate){
		super(bodySize, ID, Constants.MEMORY_TYPE_INVINDEX, isAllocate);
	}

	// 相対ポインタ対応
	public LookupPointer[] getInvertIndex(int ptr){
		if (ptr > this.bodySize - (2 * RELPTR)) return null;

		LookupPointer[] retval = new LookupPointer[2];
		retval[0] = ByteConverter.getRelativePtr(getBody(ptr, RELPTR));
		if (retval[0].equals(Constants.EMPTY_RELATIVE_PTR))
			retval[0] = null;
		else retval[0].block += this.getID();
		ptr += RELPTR;
		retval[1] = ByteConverter.getRelativePtr(getBody(ptr, RELPTR));
		// こんなことは普通はないはず
		if (retval[1].equals(Constants.EMPTY_RELATIVE_PTR))
			retval[1] = null;
		else retval[1].block += this.getID();

		return retval;
	}

	// 末尾に追加するのみ 相対ポインタ対応
	public LookupPointer setInvertIndex(LookupPointer prevPtr, LookupPointer docPtr){
		if (bodyVacancy < 2 * RELPTR) return null;

		int ptr = bodySize - bodyVacancy;
		bodyVacancy -= 2 * RELPTR;
		opt_length++;

		if (prevPtr == null){
			prevPtr = Constants.EMPTY_RELATIVE_PTR;
		}else{
			prevPtr.block -= this.getID();
		}
		setBody(ByteConverter.setRelativePtr(prevPtr), ptr);
		ptr += RELPTR;
		docPtr.block -= this.getID();
		setBody(ByteConverter.setRelativePtr(docPtr), ptr);
		// 後で使う人のために戻しておく
		docPtr.block += this.getID();

		return new LookupPointer(this.getID(), ptr - RELPTR);
	}

	public int getLeft(){
		return bodyVacancy / (2 * RELPTR);
	}

	@Override
	public int getOptionSize(){
		return 1;
	}

	@Override
	public byte[] getOptionByteStream(){
		return ByteConverter.intToByte(opt_length, 4);
	}

	@Override
	public void setOption(int option, int value){
		if (option == 0) opt_length = value;
	}

	@Override
	public String getClassName(){
		return new String("InvertIndexBlock");
	}

	@Override
	public byte[] getData() throws IOException{
		throw new NoSuchMethodError("Unimplemented method");
	}

	@Override
	public void setData(byte[] array) throws IOException{
		throw new NoSuchMethodError("Unimplemented method");
	}

}
